跳到主要内容

Lombok 常用方法

参考资料 Java中优雅的使用Lombok

什么是 Lombok

Lombok 是一种 Java实用工具,可用来帮助开发人员消除 Java 的冗长的代码,尤其是对于简单的 Java 对象(POJO), 它通过注释实现这一目的。一个标准的 Java bean 一般具有若干属性,每个属性具有 getter()setter() 方法,Lombok 中也用到了注解,它在编译源代码期间自动帮我们生成这些方法,并没有如反射那样降低程序的性能。所以 JVM 实际运行的代码,和我们手动编写的包含了各种工具方法的类相同。

配置环境

安装插件等下次用到再补充

添加 Maven 依赖

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
<scope>provided</scope>
</dependency>

注解方法一览

val: final 像动态语言一样,声明一个 final 的变量。

var: 同JDK10,就是类型推断

@Data:注解在类上,将类提供的所有属性都添加get、set方法,并添加、equals、canEquals、hashCode、toString方法

@Setter:注解在类上,为所有属性添加set方法、注解在属性上为该属性提供set方法

@Getter:注解在类上,为所有的属性添加get方法、注解在属性上为该属性提供get方法

@NotNull:在参数中使用时,如果调用时传了null值,就会抛出空指针异常

@Synchronized 用于方法,可以锁定指定的对象,如果不指定,则默认创建一个对象锁定

@Log 作用于类,创建一个log属性

@Builder:使用builder模式创建对象

@NoArgsConstructor:创建一个无参构造函数

@AllArgsConstructor:创建一个全参构造函数

@ToString:创建一个toString方法

@Accessors(chain = true)使用链式设置属性,set方法返回的是this对象。

@RequiredArgsConstructor:创建对象, 例: 在class上添加@RequiredArgsConstructor(staticName = "of")会创建生成一个静态方法

@UtilityClass:工具类

@ExtensionMethod:设置父类

@FieldDefaults:设置属性的使用范围,如private、public等,也可以设置属性是否被final修饰。

@Cleanup: 关闭流、连接点。

@EqualsAndHashCode:重写equals和hashcode方法。

@toString:创建toString方法。

@Cleanup: 用于流等可以不需要关闭使用流对象.

申明是 final 类型

public static void main(String[] args) {

val setVar = new HashSet<String>();
val listsVar = new ArrayList<String>();
val mapVar = new HashMap<String, String>();

//=>上面代码相当于如下:
final Set<String> setVar2 = new HashSet<>();
final List<String> listsVar2 = new ArrayList<>();
final Map<String, String> maps2 = new HashMap<>();

}

非空检查

@NonNull 注解能够为方法或构造函数的参数提供非空检查。

public void notNullExample(@NonNull String string) {
//方法内的代码
}

//=>上面代码相当于如下:

public void notNullExample(String string) {
if (string != null) {
//方法内的代码相当于如下:
} else {
throw new NullPointerException("null");
}
}

自动释放资源

@Cleanup 注解能够自动释放资源。

public   void jedisExample(String[] args) {
try {
@Cleanup Jedis jedis = redisService.getJedis();
} catch (Exception ex) {
logger.error(“Jedis异常:”,ex)
}

//=>上面代码相当于如下:
Jedis jedis= null;
try {
jedis = redisService.getJedis();
} catch (Exception e) {
logger.error(“Jedis异常:”,ex)
} finally {
if (jedis != null) {
try {
jedis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

自动生成 Getter、Setter

@Getter/@Setter 注解可以针对类的属性字段自动生成 Get/Set 方法。

public class OrderCreateDemoReq{

@Getter
@Setter
private String customerId;

@Setter
@Getter
private String poolId;

//其他代码……
}

//上面请求Req类的代码相当于如下:

public class OrderCreateDemoReq{
private String customerId;
private String poolId;

public String getCustomerId(){
return customerId;
}

public String getPoolId(){
return poolId;
}

public void setCustomerId(String customerId){
this.customerId = customerId;
}

public void setPoolId(String poolId){
this.pool = pool;
}

}

生成 ToString

@ToString 注解,为使用该注解的类生成一个 toString 方法,默认的 toString 格式为:

ClassName(fieldName=fieldValue ,fieldName1=fieldValue)
@ToString(callSuper=true,exclude="someExcludedField")
public class Demo extends Bar {

private boolean someBoolean = true;
private String someStringField;
private float someExcludedField;

}

//上面代码相当于如下:

public class Demo extends Bar {

private boolean someBoolean = true;
private String someStringField;
private float someExcludedField;

@Override
public String toString() {
return "Foo(super=" + super.toString() +
", someBoolean=" + someBoolean +
", someStringField=" + someStringField + ")";
}
}

自动生成 equals 和 hashCode 方法

@EqualsAndHashCode(exclude = {"id"}, callSuper =true)
public class LombokDemo extends Demo{
private int id;
private String name;
private String gender;
}

//上面代码相当于如下:

public class LombokDemo extends Demo{

private int id;
private String name;
private String gender;

@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != this.getClass()) return false;
if (!super.equals(o)) return false;
final LombokDemo other = (LombokDemo)o;
if (this.name == null ? other.name != null : !this.name.equals(other.name)) return false;
if (this.gender == null ? other.gender != null : !this.gender.equals(other.gender)) return false;
return true;
}

@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = result * PRIME + super.hashCode();
result = result * PRIME + (this.name == null ? 0 : this.name.hashCode());
result = result * PRIME + (this.gender == null ? 0 : this.gender.hashCode());
return result;
}

}

生成几种构造方法

@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor,这几个注解分别为类自动生成了无参构造器、指定参数的构造器和包含所有参数的构造器。

@RequiredArgsConstructor(staticName = "of") 
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {

private int x, y;
@NonNull private T description;

@NoArgsConstructor
public static class NoArgsExample {
@NonNull private String field;
}

}

//上面代码相当于如下:
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {

private int x, y;
@NonNull private T description;

@NoArgsConstructor
public static class NoArgsExample {
@NonNull private String field;
}

}

public class ConstructorExample<T> {
private int x, y;
@NonNull private T description;

private ConstructorExample(T description) {
if (description == null) throw new NullPointerException("description");
this.description = description;
}

public static <T> ConstructorExample<T> of(T description) {
return new ConstructorExample<T>(description);
}

@java.beans.ConstructorProperties({"x", "y", "description"})
protected ConstructorExample(int x, int y, T description) {
if (description == null) throw new NullPointerException("description");
this.x = x;
this.y = y;
this.description = description;
}

public static class NoArgsExample {
@NonNull private String field;

public NoArgsExample() {
}
}
}

Data 注解全部生成

@Data 注解作用比较全,其包含注解的集合 @ToString@EqualsAndHashCode,所有字段的 @Getter 和所有非 final 字段的 @Setter, @RequiredArgsConstructor。其示例代码可以参考上面几个注解的组合。

建造者模式和单例

@Builder 注解提供了一种比较推崇的构建值对象的方式。 @Singular 用于创建单例

@Builder 
public class BuilderExample {

private String name;
private int age;

@Singular private Set<String> occupations;

}

//上面代码相当于如下:

public class BuilderExample {

private String name;
private int age;
private Set<String> occupations;

BuilderExample(String name, int age, Set<String> occupations) {
this.name = name;
this.age = age;
this.occupations = occupations;
}

public static BuilderExampleBuilder builder() {
return new BuilderExampleBuilder();
}

public static class BuilderExampleBuilder {

private String name;
private int age;
private java.util.ArrayList<String> occupations;

BuilderExampleBuilder() {
}

public BuilderExampleBuilder name(String name) {
this.name = name;
return this;
}

public BuilderExampleBuilder age(int age) {
this.age = age;
return this;
}

public BuilderExampleBuilder occupation(String occupation) {
if (this.occupations == null) {
this.occupations = new java.util.ArrayList<String>();
}
this.occupations.add(occupation);
return this;
}

public BuilderExampleBuilder occupations(Collection<? extends String> occupations) {
if (this.occupations == null) {
this.occupations = new java.util.ArrayList<String>();
}
this.occupations.addAll(occupations);
return this;
}

public BuilderExampleBuilder clearOccupations() {
if (this.occupations != null) {
this.occupations.clear();
}
return this;
}

public BuilderExample build() {
Set<String> occupations = new HashSet<>();
return new BuilderExample(name, age, occupations);
}

@Override
public String toString() {
return "BuilderExample.BuilderExampleBuilder(name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")";
}
}
}

@Synchronized 注解

@Synchronized 注解类似 Java 中的 Synchronized 关键字,但是可以隐藏同步锁。

public class SynchronizedExample { 

private final Object readLock = new Object();

@Synchronized
public static void hello() {
System.out.println("world");
}

@Synchronized("readLock")
public void foo() {
System.out.println("bar");
}

//上面代码相当于如下:

public class SynchronizedExample {

private static final Object $LOCK = new Object[0];
private final Object readLock = new Object();

public static void hello() {
synchronized($LOCK) {
System.out.println("world");
}
}

public void foo() {
synchronized(readLock) {
System.out.println("bar");
}
}

}